<?php
namespace app\api\services;

use app\api\cache\KeysUtil;
use app\api\cache\Marketing;
use app\api\cache\RedisCache;
use app\api\consDir\CommunityConst;
use app\api\consDir\OrderPrefixConst;
use app\api\consDir\SandConst;
use app\common\libs\Singleton;
use app\common\models\Community\Community;
use app\common\models\Community\CommunityTasksLog;
use app\common\models\Community\CommunityUser;
use app\common\models\Member\Member;
use app\common\models\Member\MemberGxzLog;
use app\common\models\Order\Order;
use app\common\models\Order\OrderAddress;
use app\common\models\Order\OrderExpress;
use app\common\models\Order\OrderGoods;
use app\common\models\Order\OrderPay;
use app\common\models\Order\OrderShop;
use app\common\models\Order\Postage;
use app\common\models\Shop\GoodsSku;
use app\common\models\Shop\Shop;
use think\Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

class OrderService
{
    use Singleton;

    public function getOrderOrderSumByShopId($shopId): float
    {
        $where = [
            ['shop_id', '=', $shopId],
        ];
        return OrderShop::getInstance()->where($where)->sum('sell_price');
    }

    public function getOrderCountByShopId($shopId): int
    {
        $where = [
            ['shop_id', '=', $shopId],
        ];
        return OrderShop::getInstance()->where($where)->count('id');
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function taskOrder($order, $checkUserId = 0): bool
    {
        $where = [
            ['order_no','=', $order['orderNo']],
            ['status','in', [2,10]],
        ];
        $goodsOrder = OrderGoods::getInstance()->where($where)->select();
        if (empty($goodsOrder)) {
            return false;
        }
        $orderNo = $order['orderNo'];
        Order::getInstance()->startTrans();
        try {
            $update = [
                'status'  => 3, //已收货
                'task_at' => date('Y-m-d H:i:s'),
                'completion_at' => date('Y-m-d H:i:s')
            ];

            //修改主单状态
            Order::getInstance()->where($where)->update($order['serviceId'] > 0 ? array_merge($update,['check_user_id' => $checkUserId]) : $update);
            OrderGoods::getInstance()->where($where)->update($update);
            OrderShop::getInstance()->where($where)->update($update);
            //修改shop单状态
            foreach ($goodsOrder as $val) {
                if ($val['shopId']) {
                    //获取商户信息
                    $shopInfo = ShopService::getInstance()->getShopInfoById($val['shopId'], 'id,shop_name,user_id,status,score_rate,gxz_rate,platform_fee');
                    //给商户钱
                    $goodsAllAmount = bcadd($val['payPrice'], $val['sale'], 2);
                    //扣除让利比例金额
                    $goodsAllAmount = bcsub($goodsAllAmount, bcmul($goodsAllAmount, $shopInfo['platformFee'] * 0.01, 2), 2);
                    //扣除商家优惠券金额
                    if ($val['shopSale'] > 0) {
                        $goodsAllAmount = bcsub($goodsAllAmount, $val['shopSale'], 2);
                    }
                    // discountSale 会员等级折扣 由平台承当，这里不需要处理，包含在 sale 里面给商家了

                    //加商户总金额
                    $msg = '商品' . $val['goodsTitle'] . '出售成功，获得' . $goodsAllAmount;
                    MemberService::getInstance()->addFinanceLog($shopInfo['userId'], 'order_task', $goodsAllAmount, 2, $msg);

                    $gxzRate = $val['gxzRate'] > 0 ? $val['gxzRate'] : $shopInfo['gxzRate'];
                    if ($gxzRate > 0) {
                        $money = bcmul($val['payPrice'], $gxzRate * 0.01, 4);
                        if ($money > 0) {
                            $msg = '线上订单消费，赠送贡献值，订单号' . $orderNo;
                            MemberService::getInstance()->addFinanceLog($val['userId'], 'online', $money, 7, $msg, $val['orderNo']);
                        }
                    }
                    //分润池
                    //1线下直付单 2线上单 3线下单 4供应链
                    //1线上订单 2线下订单 3怡亚通订单 4社区订单 5礼包订单
                    $profit = 0;
                    $type = 2;
                    if ($val['orderType'] == 2) {
                        $profit = bcmul($val['payPrice'], bcmul($shopInfo['platformFee'], 0.01, 4), 4);
                        $type   = 1;
                    }
                    MemberService::getInstance()->profitPoolLog($val['userId'], $val['payPrice'], $orderNo, $profit, $type);
                }
                //供应链
                if ($val['orderType'] == 4) {
                    if ($val['gxzRate'] > 0) {
                        $money = bcmul($val['payPrice'], $val['gxzRate'] * 0.01, 4);
                        if ($money > 0) {
                            $msg = '供应连订单消费，赠送贡献值，订单号' . $orderNo;
                            MemberService::getInstance()->addFinanceLog($val['userId'], 'online', $money, 7, $msg, $val['orderNo']);
                        }
                    }
                    //供应链
                    $profit = bcsub($val['sellPrice'], $val['costPrice'], 4);
                    $type   = 3;
                    MemberService::getInstance()->profitPoolLog($val['userId'], $val['payPrice'], $orderNo, $profit, $type);
                }
                $this->dividend($val);
            }
            $subOrderItems = OrderShop::getInstance()->where('order_no',$order['orderNo'])->select();
            foreach($subOrderItems as $subItem){
                $shopInfo = ShopService::getInstance()->getShopInfoById($subItem['shopId'], 'id,shop_name,user_id,status,score_rate,gxz_rate,platform_fee');
                //给商户钱
                $goodsAllAmount = bcadd($subItem['payPrice'], $subItem['sale'], 2);
                //扣除让利比例金额
                $goodsAllAmount = bcsub($goodsAllAmount, bcmul($goodsAllAmount, $shopInfo['platformFee'] * 0.01, 2), 2);
                //扣除商家优惠券金额
                if ($subItem['shopSale'] > 0) {
                    $goodsAllAmount = bcsub($goodsAllAmount, $subItem['shopSale'], 2);
                }
                if($order['isDirect'] == 0){
                    $goodsAllAmount = bcadd($goodsAllAmount,$subItem['deduction'],2);
                    Log::info($orderNo . '公司杉德账号转账给用户' . $goodsAllAmount);
                    //$goodsAllAmount = env('test.is_test') ? 0.01 : $goodsAllAmount;
                    $ret = SandService::getInstance()->transfer($goodsAllAmount, env('sand.consumeMid'), SandConst::PREFIX . $shopInfo['userId'], 0, getNo(OrderPrefixConst::TR));
                    if (!isset($ret['code']) || $ret['code'] != 1) {
                        throw new Exception($orderNo . $ret['data']);
                    }
                }else{
                    //解冻
                    Log::info($orderNo . '解冻用户金额' . $goodsAllAmount);
                    //$goodsAllAmount = env('test.is_test') ? 0.01 : $goodsAllAmount;
                    $ret = SandService::getInstance()->unfreeze(getNo('unFreeze'),$subItem['freezeOrderNo'],$goodsAllAmount);
                    if (!isset($ret['resultStatus']) || $ret['resultStatus'] != 'success') {
                        throw new Exception($orderNo . $ret['errorDesc']);
                    }
                }
            }
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            Order::getInstance()->rollback();
            return false;
        }
        Order::getInstance()->commit();
        return true;
    }

    public function orderExpress($orderNo, $goodsId): array
    {
        $where = [
            'order_no' => $orderNo,
            'goods_id' => $goodsId,
        ];
        $express = OrderExpress::getInstance()->where($where)->find();

        if (empty($express)) {
            return [];
        }
        // $express['expressNo'] = 'YT8953807276859';
        // $express['expressName'] = '韵达快递';
        $data = ExpressService::getInstance()->query([
            // 'expressCode' => 'yuantong',
            'expressNo' => $express['expressNo'],
        ]);

        return [
            'expressNo'   => $express['expressNo'],
            'expressName' => $express['expressName'] ?? '',
            'expressCode' => $data['com'] ?? '',
            'expressList' => $data['data'] ?? [],
        ];
    }

    public function getOrderShopInfo($orderNo): array
    {
        $where = [
            'order_no' => $orderNo,
        ];
        $field     = 'shop_id,shop_name,pay_price,postage,sale,order_no';
        $orderShop = OrderShop::getInstance()->where($where)->field($field)->select();
        $orderShop = empty($orderShop) ? [] : $orderShop->toArray();
        if (empty($orderShop)) {
            return [];
        }
        foreach ($orderShop as &$v) {
            $where = [
                ['order_no', '=', $v['orderNo']],
                ['shop_id', '=', $v['shopId']],
            ];
            $field          = 'goods_id,goods_img,goods_title,id,sku_title,is_freight_insurance,is_seven,quantity,sell_price,status';
            $v['goodsInfo'] = OrderGoods::getInstance()->where($where)->field($field)->select()->toArray();
            //读取店铺信息
            $v['shop_logo']         = "";
            $v['shop_business_img'] = "";
            $v['kf_phone']          = "";
            if ($v['shopId'] != 0) {
                $shopWhere              = ['id' => (int) $v['shopId']];
                $shopInfos              = Shop::getInstance()->where($shopWhere)->find();
                $v['shop_logo']         = $shopInfos['shop_logo'];
                $v['shop_business_img'] = $shopInfos['shop_business_img'];
                $v['kf_phone']          = $shopInfos['kf_phone'];
            }
        }

        return $orderShop;
    }

    public function getOrderAddress($orderNo): array
    {
        $where = [
            'order_no' => $orderNo,
        ];
        $field   = 'province,city,country,street,comm,address,phone,real_name';
        $address = OrderAddress::getInstance()->field($field)->where($where)->find();
        return empty($address) ? [] : $address->toArray();
    }

    public function delOrder($orderInfo)
    {
        Order::getInstance()->startTrans();
        try {
            //修改退款状态
            $order = Order::getInstance()
                ->where('id', $orderInfo['id'])
                ->update(['deleted' => 1]);
            if ( ! $order) {
                return false;
            }

            if ($orderInfo['orderType'] != 4) {
                $orderShop = OrderShop::getInstance()
                    ->where('order_no', $orderInfo['orderNo'])
                    ->update(['deleted' => 1]);
                if ( ! $orderShop) {
                    Order::getInstance()->rollback();
                    return false;
                }
            }

            $orderGoods = OrderGoods::getInstance()
                ->where('order_no', $orderInfo['orderNo'])
                ->update(['deleted' => 1]);

            Order::getInstance()->commit();
            return true;

        } catch (\Exception $e) {

        }
        return false;
    }

    /**
     * @param $orderInfo
     * @return bool
     */
    public function orderRefund($orderInfo)
    {
        $where = [
            'order_no' => $orderInfo['orderNo'],
        ];
        $orderGoodsList = OrderGoods::getInstance()
            ->field(['goods_id', 'sku_id', 'quantity'])
            ->where($where)
            ->select()->toArray();

        Order::getInstance()->startTrans();
        try {
            //修改退款状态
            $order = Order::getInstance()
                ->where('id', $orderInfo['id'])
                ->update(['status' => 7, 'refund_at' => date('Y-m-d H:i:s')]);

            if ( ! $order) {
                return false;
            }

            $orderShop = OrderShop::getInstance()
                ->where('order_no', $orderInfo['orderNo'])
                ->update(['status' => 7, 'refund_at' => date('Y-m-d H:i:s')]);
            if ( ! $orderShop) {
                Order::getInstance()->rollback();
                return false;
            }

            $orderGoods = OrderGoods::getInstance()
                ->where('order_no', $orderInfo['orderNo'])
                ->update(['status' => 7, 'refund_at' => date('Y-m-d H:i:s')]);
            if ( ! $orderGoods) {
                Order::getInstance()->rollback();
                return false;
            }
            if ($orderInfo['payAmount'] > 0) {
                $msg     = '订单取消，退回余额：' . $orderInfo['payAmount'];
                $finance = MemberService::getInstance()
                    ->addFinanceLog($orderInfo['userId'], 'order_cancel', $orderInfo['payAmount'], 1, $msg);
                if ( ! $finance) {
                    Order::getInstance()->rollback();
                    return false;
                }
            }
            if ($orderInfo['payPrice'] > 0) {
                $refund = WechatPayService::getInstance()->refund($orderInfo, $orderInfo['payPrice']);
                if ( ! $refund) {
                    Order::getInstance()->rollback();
                    return false;
                }
            }

            // 线上线下单取消订单加库存减销量
            // 1线下直付单 2线上单 3线下单 4供应链
            if (in_array($orderInfo['orderType'], [1, 2, 3])) {
                foreach ($orderGoodsList as $item) {
                    $goods_id     = $item['goodsId'];
                    $goods_sku_id = $item['skuId'];
                    \think\facade\Db::table('goods')
                        ->where('id', $goods_id)
                        ->dec('goods_sales', $item['quantity'])
                        ->inc('goods_inventory', $item['quantity'])
                        ->update();
                    if ($goods_sku_id > 0) {
                        \think\facade\Db::table('goods_sku')
                            ->where('goods_id', $goods_id)
                            ->where('id', $goods_sku_id)
                            ->dec('goods_sales', $item['quantity'])
                            ->inc('goods_inventory', $item['quantity'])
                            ->update();
                    }
                }
            }

            Order::getInstance()->commit();
            return true;

        } catch (\Exception $e) {

            Order::getInstance()->rollback();
        }
        return false;
    }

    /**
     * @param $uId
     * @param $type
     * @param $orderType
     * @param $page
     * @param $pageSize
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function orderList($uId, $type, $orderType, $page, $pageSize): array
    {
        //1全部 2待付款 3待发货 4待收货 5待评价 6售后
        switch ($type) {
            case 1:
                $where = [
                    ['user_id', '=', $uId],
                    ['deleted', '=', 0],
                ];
                break;
            case 2:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 0],
                    ['deleted', '=', 0],
                ];
                break;
            case 3:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 1],
                    ['deleted', '=', 0],
                ];
                break;
            case 4:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 2],
                    ['deleted', '=', 0],
                ];
                break;
            case 5:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 3],
                    ['is_comment', '=', 0],
                    ['deleted', '=', 0],
                ];
                break;
            case 10:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 10],
                    ['deleted', '=', 0],
                ];
                break;
            default:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', 'in', [5, 6]],
                    ['deleted', '=', 0],
                ];
        }
        if ($orderType == 2) {
            $where[] = ['order_type', 'in', [2, 4]];
        } else {
            $where[] = ['order_type', 'in', [1, 3]];
        }

        $list = Order::getInstance()
            ->where($where)
            ->limit(($page - 1) * $pageSize, $pageSize)
            ->field('id,status,order_no,user_id,sell_price,order_type,pay_price,postage,sale,pay_at,create_at,expire_at,is_comment,service_id,check_user_id,deduction')
            ->order('id desc')
            ->select();
        if (empty($list)) {
            return [];
        }
        $list = $list->toArray();

        foreach ($list as &$val) {
            $where = [
                ['order_no', '=', $val['orderNo']],
            ];
            $orderShop = OrderShop::getInstance()->where($where)->find();
            // 供应商订单 没有 orderShop 数据，没有 shop_id
            if (empty($orderShop['shopId'])) {
                $val['shopInfo'] = (object) [];
            } else {
                $val['shopInfo'] = ShopService::getInstance()->getShopInfoById(
                    $orderShop['shopId'],
                    'id,shop_logo,shop_name,kf_phone');
            }

            $orderInfo         = OrderGoods::getInstance()->where($where)->field('is_freight_insurance,is_seven,status,quantity,sell_price,goods_id,goods_title,sku_title,goods_img')->select();
            $val['createAt']   = date('Y-m-d H:i', strtotime($val['createAt']));
            $expireTime        = strtotime($val['expireAt']) - time();
            $val['expireTime'] = $expireTime > 0 ? $expireTime : 0;
            $val['goodsInfo']  = empty($orderInfo) ? [] : $orderInfo->toArray();
            $where = [
                ['order_no','=',$val['orderNo']],
            ];
            $count = CommunityTasksLog::getInstance()->where($where)->count();
            $val['isCommunity'] = 0;
        }
        return $list;
    }


    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function payCallback($orderNo, string $tradeNo = '', $payNo = ''): bool
    {
        $date = date('Y-m-d H:i:s');
        //判断订单类型
        $orderData = Order::getInstance()->where(['order_no' => $orderNo])->find();
        if (empty($orderData)) {
            return false;
        }

        if($orderData['deduction'] > 0){
            MemberService::getInstance()->addFinanceLog($orderData['userId'], 'buy', $orderData['deduction'], 8, '订单抵扣', $orderNo,1,0,0);
        }

        //待发货
        $orderDate = ['status' => 1, 'pay_at' => $date, 'trade_no' => $tradeNo];
        if ($orderData['order_type'] == 1) {
            //线下直接支付订单，默认为完成状态
            $orderDate = ['status' => 4, 'pay_at' => $date, 'trade_no' => $tradeNo, 'completion_at' => $date];
        }

        //自提
        if($orderData['order_type'] == 2 && $orderData['service_id'] > 0){
            $orderDate = ['status' => 10, 'pay_at' => $date, 'trade_no' => $tradeNo];
        }
        $where = [
            'order_no' => $orderNo,
        ];
        $orderGoodsList = OrderGoods::getInstance()
            ->field(['goods_id', 'sku_id', 'quantity'])
            ->where($where)
            ->select()->toArray();
        try {
            OrderGoods::getInstance()->where($where)->update($orderDate);
            if ($orderData['order_type'] != 4) {
                OrderShop::getInstance()->where($where)->update($orderDate);
            }
            //$isDirect = ShopService::getInstance()->IsDirectByOrderNo($orderNo);
            // order_type 1线下直付单 2线上单 3线下单(有商品)  4供应链
            //线下直推分佣
            if ($orderData['order_type'] == 1) {
                $this->dividend($orderData);
                $subOrderItems = OrderShop::getInstance()->where($where)->select();
                //$price  = $orderData['sellPrice'] > 0 ? $orderData['sellPrice'] : $orderData['payPrice'];
                if ( ! empty($subOrderItems)) {
                    $msg = '线下支付订单';
                    foreach ($subOrderItems as $key => $subItem) {
                        $shopId = $subItem['shopId'];
                        $price  = $subItem['payPrice'];
                        //线下货款
                        $shop = Shop::getInstance()->where('id', $shopId)->find();
                        // 扣除让利
                        // platformFee 让利比例
                        /*if($orderData['order_type'] == 1){
                            $subItem['sellPrice'] =  $subItem['payPrice'];
                        }*/
                        $reduceMoney = bcmul($subItem['sellPrice'], $shop['platformFee'] * 0.01, 2);
                        // 线下货款 = 实付金额 - 让利金额(sellPrice * 让利比例) + 平台优惠 + 优惠折扣(用户等级优化折扣)
                        $goodsMoney = $subItem['payPrice'] - $reduceMoney + $subItem['platformSale'] + ($subItem['discountSale'] ?? 0) + $subItem['deduction'];
                        $goodsMoney = bcadd($goodsMoney,0,2);
                        MemberService::getInstance()->addFinanceLog($shop['userId'], 'order_task', $goodsMoney, 2, $msg);


                        //商家后台积分赠送比例，是用户获得数字积分的比例，比如设置为10% ，即用户消费100 可获得10个数字积分
                        $gxzRate = OrderGoods::getInstance()->where(['order_no' => $orderNo, 'shop_id' => $shopId])->value('gxz_rate');
                        if ($gxzRate > 0) {
                            $shop['gxzRate'] = $gxzRate;
                        }
                        if ($shop['gxzRate'] > 0) {
                            $money = bcmul($price, $shop['gxzRate'] * 0.01, 4);
                            if ($money > 0) {
                                //$msg = '购买商品，赠送数字积分';
                                //MemberService::getInstance()->addFinanceLog($orderData['userId'], 'offline', $money, 6, $msg, $orderNo, 2);
                                $msg = '线下订单消费，赠送贡献值，订单号' . $orderNo;
                                MemberService::getInstance()->addFinanceLog($subItem['userId'], 'offline', $money, 7, $msg, $orderNo);
                            }
                        }
                        //加入分润池
                        $profit = bcmul($price, $shop['platformFee'] * 0.01, 4);
                        MemberService::getInstance()->profitPoolLog($subItem['userId'], $subItem['payPrice'], $orderNo, $profit, 2);
                        $msg = '商家货款，订单号'.$orderNo;
                        ShopService::getInstance()->payToShopSand($orderNo,$payNo,$orderData['isDirect'],$subItem['payPrice'],$goodsMoney,$shop['userId'],$orderData['payType'],$msg);
                    }
                }
            }
            if ($orderData['order_type'] == 4) {
                $orderAddress = OrderAddress::getInstance()
                    ->where('order_no', $orderData['orderNo'])
                    ->find();
                $ret = SupplyService::getInstance()->submitOrder(
                    $orderData['goodsList'],
                    $orderAddress['realName'],
                    $orderAddress['address'],
                    $orderAddress['phone'],
                    $orderData['addrPath'],
                    $orderData['orderNo']);
                Log::info('供应链下单返回参数:' . json_encode($ret, 320));
                if (empty($ret) || $ret['status'] != 200) {
                    return false;
                }
                $orderDate['supply_order_no'] = $ret['data']['orderList'][0]['orderSn'];
            }
            //线上商家 order_type线下直付单 2线上单 3线下单 4供应链
            if(in_array($orderData['order_type'],[2,3]) && $orderData['pay_type'] == 4){
                $subOrderItems = OrderShop::getInstance()->where($where)->select();
                foreach($subOrderItems as $subItem){
                    $shop = Shop::getInstance()->where('id', $subItem['shopId'])->find();

                    $reduceMoney = bcmul($subItem['sellPrice'], $shop['platformFee'] * 0.01, 2);
                    // 线上货款 = 实付金额 - 让利金额(sellPrice * 让利比例) + 平台优惠 + 优惠折扣(用户等级优化折扣)
                    //$goodsMoney = $subItem['sellPrice'] - $reduceMoney + $subItem['platformSale'] + ($subItem['discountSale'] ?? 0);
                    $goodsMoney = bcsub(bcsub($subItem['sellPrice'],$reduceMoney,2),$subItem['shopSale'],2);
                    if($orderData['isDirect'] == 1){
                        $ret = SandService::getInstance()->transferConfirm(getNo(OrderPrefixConst::TC), $payNo, $subItem['payPrice'], 'confirm', SandConst::PREFIX . $shop['userId']);
                        Log::info($orderNo . '线上商家杉德确认转账返回' . json_encode($ret, 256));
                        if (!isset($ret['resultStatus']) || $ret['resultStatus'] != 'success') {
                            Log::error(json_encode($ret,256));
                            throw new Exception($orderNo . $ret['errorDesc']);
                        }
                        //冻结金额
                        $ret = SandService::getInstance()->freeze(getNo('freeze'),$goodsMoney,$shop['userId']);
                        Log::error(json_encode($ret, 256));
                        if (isset($ret['resultStatus']) && $ret['resultStatus'] != 'success') {
                            throw new Exception($orderNo . '冻结金额' . $ret['errorDesc']);
                        }
                        $subItem->freeze_order_no = $ret['outOrderNo'];
                        $subItem->save();
                    }
                }
            }
            Order::getInstance()->where($where)->update($orderDate);



            // 线上线下单付款减库存加销量
            // 1线下直付单 2线上单 3线下单 4供应链
            if (in_array($orderData['order_type'], [1, 2, 3])) {
                foreach ($orderGoodsList as $item) {
                    $goods_id     = $item['goodsId'];
                    $goods_sku_id = $item['skuId'];
                    \think\facade\Db::table('goods')
                        ->where('id', $goods_id)
                        ->inc('goods_sales', $item['quantity'])
                        ->dec('goods_inventory', $item['quantity'])
                        ->update();
                    if ($goods_sku_id > 0) {
                        \think\facade\Db::table('goods_sku')
                            ->where('goods_id', $goods_id)
                            ->where('id', $goods_sku_id)
                            ->inc('goods_sales', $item['quantity'])
                            ->dec('goods_inventory', $item['quantity'])
                            ->update();
                    }
                }
            }
        } catch (\Exception $e) {
            Log::error($orderNo . $e->getMessage());
            return false;
        }
        return true;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function dividend($order): bool
    {
        if (empty($order)) {
            return false;
        }

        $arr   = [1 => 'first_offline', 2 => 'first_online', 3 => 'first_offline', 4 => 'first_online'];
        $where = [
            ['user_id', '=', $order['userId']],
            ['log_type', 'in', ['first_online','first_offline']],
        ];
        $count = MemberGxzLog::getInstance()->where($where)->count();
        if ($count <= 0) {
            $nameArr = ['first_online' => '线上消费', 'first_offline' => '线下消费'];
            MemberService::getInstance()->sendNewTaskGxz($order['userId'], $arr[$order['orderType']], '第一次' . $nameArr[$arr[$order['orderType']]]);
        }

        $dividend = Marketing::getKeyData('marketing', 'dividend');
        if(empty($dividend)){
            return false;
        }
        $shopId = OrderShop::getInstance()->where('order_no', $order['orderNo'])->value('shop_id');
        if(isset($dividend['user_status']) && $dividend['user_status'] == 1){
            $price = $order['payPrice'];
            $remark = '消费金额的';
            if(isset($dividend['user_dividend_type']) && $dividend['user_dividend_type'] == 1){
                //按商家服务或产品利润
                //order_type 1线下直付单 2线上单 3线下单 4供应链
                if($order['orderType'] == 4){
                    $price = bcsub($order['sellPrice'],$order['costPrice'],2);
                }else{
                    $platformFee = Shop::getInstance()->where('id',$shopId)->value('platform_fee');
                    $price = bcmul($order['sellPrice'],$platformFee*0.01,2);
                }
                $price = bcsub($price,$order['platformSale'],2);
                $remark = '让利的';
            }

            if($price <= 0){
                return false;
            }
            //直推会员消费收益 会员消费金额的0.7%
            //$rate        = CommunityService::getInstance()->getCommunityConfig('direct_member_earnings');
            $rate        = $dividend['user_invite_rate'];
            $inviteMoney = bcmul($price, $rate * 0.01, 4);
            $member      = Member::getInstance()->where('id', $order['userId'])->find();
            if ($inviteMoney > 0 && $member['inviteId']) {
                $msg = '推广会员消费，获得直推会员消费收益，'. $remark . $rate . '%';
                MemberService::getInstance()->addFinanceLog($member['inviteId'], 'direct_member_earnings', $inviteMoney, 5, $msg, $order['orderNo'], 1, 2);
            }

            //社区会员消费收益
            $commId = Community::getInstance()->where('comm_id', $member['commId'])->value('id');
            $where  = [
                ['community_id', '=', $commId],
                ['community_status', 'in', [CommunityConst::CHECK_STATUS, CommunityConst::PERMANENT_STATUS]],
            ];
            $community = CommunityUser::getInstance()->where($where)->find();
            if ($community && $community['userId']) {
                //$rate  = CommunityService::getInstance()->getCommunityConfig('community_member_earnings');
                $rate = $dividend['user_community_partner_rate'];
                $bonus = bcmul($price, $rate * 0.01, 4);
                if ($bonus > 0) {
                    $msg = '推广会员消费，获得社区会员消费收益，'. $remark . $rate . '%';
                    MemberService::getInstance()->addFinanceLog($community['userId'], 'community_member_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                }
            }

            //服务商收益
            if(isset($dividend['user_partner_status']) && $dividend['user_partner_status'] == 1){
                $partner = MemberService::getInstance()->getMyPartnerInfo($order['userId']);
                if ($partner) {
                    if ($partner['partnerId']) {
                        $rate  = $dividend['user_partner_rate'];
                        $msg   = '推广会员消费，获得服务商收益，收益比例' . $rate . '%，订单' . $order['orderNo'];
                        $bonus = bcmul($price, $rate*0.01, 4);
                        MemberService::getInstance()->addFinanceLog($partner['partnerId'], 'spread_service_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }
            }

            //平级服务商
            if(isset($dividend['user_ping_partner_status']) && $dividend['user_ping_partner_status'] == 1){
                $userPingMember = Member::getInstance()->where('id',$order['userId'])->find();
                $myPartner = MemberService::getInstance()->getMyPartner($userPingMember);
                if ($myPartner) {
                    if ($myPartner['id']) {
                        $rate  = $dividend['user_ping_partner_rate'];
                        $msg   = '推广会员消费，获得平级服务商收益，收益比例' . $rate . '%，订单' . $order['orderNo'];
                        $bonus = bcmul($price, $rate*0.01, 4);
                        MemberService::getInstance()->addFinanceLog($myPartner['id'], 'spread_service_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }
            }

            //区域（省/市/区县）会员消费收益
            $partnerInfo = MemberService::getInstance()->getAgencyArr($member['provinceId'], $member['cityId'], $member['countryId'], $member['streetId']);
            if ($partnerInfo['provinceUid'] > 0) {
                //$rate  = CommunityService::getInstance()->getCommunityConfig('member_province_earnings');
                $rate = $dividend['user_province_rate'];
                $bonus = bcmul($price, $rate * 0.01, 4);
                if ($bonus > 0) {
                    $msg = "推广会员消费，获得区域（" . $partnerInfo['provinceName'] . "）会员消费收益，". $remark . $rate . '%';
                    MemberService::getInstance()->addFinanceLog($partnerInfo['provinceUid'], 'province_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                }
            }

            if ($partnerInfo['cityUid'] > 0) {
                //$rate  = CommunityService::getInstance()->getCommunityConfig('member_city_earnings');
                $rate = $dividend['user_city_rate'];
                $bonus = bcmul($price, $rate * 0.01, 4);
                if ($bonus > 0) {
                    $msg = "推广会员消费，获得区域（" . $partnerInfo['cityName'] . "）会员消费收益，". $remark . $rate . '%';
                    MemberService::getInstance()->addFinanceLog($partnerInfo['cityUid'], 'city_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                }
            }

            if ($partnerInfo['countryUid'] > 0) {
                //$rate  = CommunityService::getInstance()->getCommunityConfig('member_area_earnings');
                $rate = $dividend['user_area_rate'];
                $bonus = bcmul($price, $rate * 0.01, 4);
                if ($bonus > 0) {
                    $msg = "推广会员消费，获得区域（" . $partnerInfo['countryName'] . "）会员消费收益，" . $remark . $rate . '%';
                    MemberService::getInstance()->addFinanceLog($partnerInfo['countryUid'], 'area_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                }
            }
        }

        if(isset($dividend['shop_status']) && $dividend['shop_status'] == 1){
            //$shopId = OrderShop::getInstance()->where('order_no', $order['orderNo'])->value('shop_id');
            if ($shopId) {
                $platformFee = Shop::getInstance()->where('id', $shopId)->value('platform_fee');
                //让利部分
                $money = bcmul($order['sellPrice'], $platformFee * 0.01, 4);
                $money = bcsub($money,$order['platformSale'],2);
                $remark = '让利的';
                if(isset($dividend['shop_dividend_type']) && $dividend['shop_dividend_type'] == 0){
                    $money = $order['payPrice'];
                    $remark = '消费金额的';
                }
                if($money <= 0){
                    return false;
                }

                //直推商家让利收益 商家营业中让利部分3%
                $shop     = Shop::getInstance()->where('id', $shopId)->find();
                $inviteId = Member::getInstance()->where('id', $shop['userId'])->value('invite_id');
                if ($inviteId) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('direct_shop_earnings');
                    $rate = $dividend['shop_invite_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = '推广商家，获得直推商家让利收益，让利的' . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($inviteId, 'direct_shop_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }

                //社区商家让利收益
                $commId = Community::getInstance()->where('comm_id', $shop['commId'])->value('id');
                $where  = [
                    ['community_id', '=', $commId],
                    ['community_status', 'in', [CommunityConst::CHECK_STATUS, CommunityConst::PERMANENT_STATUS]],
                ];
                $community = CommunityUser::getInstance()->where($where)->find();

                if ($community && $community['userId']) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('community_shop_earnings');
                    $rate = $dividend['shop_community_partner_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = '推广商家，获得社区会员消费收益，' . $remark . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($community['userId'], 'community_shop_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }

                //服务商收益
                if(isset($dividend['shop_partner_status']) && $dividend['shop_partner_status'] == 1){
                    $partner = MemberService::getInstance()->getMyPartnerInfo($shop['userId']);
                    if ($partner) {
                        if ($partner['partnerId']) {
                            $rate  = $dividend['shop_partner_rate'];
                            $msg   = '推广商家，获得服务商收益，收益比例' . $rate . '%，订单' . $order['orderNo'];
                            $bonus = bcmul($money, $rate*0.01, 4);
                            MemberService::getInstance()->addFinanceLog($partner['partnerId'], 'spread_service_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                        }
                    }
                }

                //平级服务商
                if(isset($dividend['shop_ping_partner_status']) && $dividend['shop_ping_partner_status'] == 1){
                    $shopPingMember = Member::getInstance()->where('id',$shop['userId'])->find();
                    $myPartner = MemberService::getInstance()->getMyPartner($shopPingMember);
                    if ($myPartner) {
                        if ($myPartner['id']) {
                            $rate  = $dividend['shop_ping_partner_rate'];
                            $msg   = '推广商家，获得平级服务商收益，收益比例' . $rate . '%，订单' . $order['orderNo'];
                            $bonus = bcmul($money, $rate*0.01, 4);
                            MemberService::getInstance()->addFinanceLog($myPartner['id'], 'spread_service_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                        }
                    }
                }

                //区域（省/市/区县）商家让利收益
                $shopPartnerInfo = MemberService::getInstance()->getAgencyArr($shop['provinceId'], $shop['cityId'], $shop['countryId'], $shop['streetId']);
                if ($shopPartnerInfo['provinceUid'] > 0) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('shop_province_earnings');
                    $rate = $dividend['shop_province_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = "推广商家，获得区域（" . $shopPartnerInfo['provinceName'] . "）会员消费收益，". $remark . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($shopPartnerInfo['provinceUid'], 'shop_province_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }

                if ($shopPartnerInfo['cityUid'] > 0) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('shop_city_earnings');
                    $rate = $dividend['shop_city_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = "推广商家，获得区域（" . $shopPartnerInfo['cityName'] . "）会员消费收益，". $remark . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($shopPartnerInfo['cityUid'], 'shop_city_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }

                if ($shopPartnerInfo['countryUid'] > 0) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('shop_area_earnings');
                    $rate = $dividend['shop_area_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = "推广商家，获得区域（" . $shopPartnerInfo['countryName'] . "）会员消费收益，". $remark . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($shopPartnerInfo['countryUid'], 'shop_area_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }
            }
        }

        return true;
    }

    public function createOrder($priceInfo, $addressInfo, $couponId)
    {
        Order::getInstance()->startTrans();
        try {
            $order = $this->insertOrder($priceInfo['allList']);
            if ( ! $order) {
                return false;
            }
            if ( ! empty($addressInfo)) {
                $addressInfo['order_no'] = $priceInfo['allList']['order_no'];
                $address                 = OrderAddress::getInstance()->insert($addressInfo);
                if ( ! $address) {
                    Order::getInstance()->rollback();
                    return false;
                }
            }

            $order = OrderShop::getInstance()->insertAll($priceInfo['shopPriceList']);
            if ( ! $order) {
                Order::getInstance()->rollback();
                return false;
            }

            $order = OrderGoods::getInstance()->strict(false)->insertAll($priceInfo['goodsPriceList']);
            if ( ! $order) {
                Order::getInstance()->rollback();
                return false;
            }

            if ( ! empty($couponId)) {
                CouponService::getInstance()->updateCouponInfo($couponId);
            }

        } catch (\Exception $e) {
            Order::getInstance()->rollback();
            return false;
        }
        Order::getInstance()->commit();
        return $priceInfo['allList']['order_no'];
    }

    public function insertOrder($data)
    {
        return Order::getInstance()->insert($data);
    }

    /**
     * @param $goodsInfo
     * @param $uId
     * @param $option [
     *        'special_id' => $special_id, // 专题ID
     *        'level_discount' => $level_discount, //  会员等级折扣率 [0, 1)
     * ]
     * @return array
     */
    public function getOrderPrice($goodsInfo, $uId, $option = []): array
    {
        $orderNo   = getNo('OL');
        $orderType = 2;
        //总价
        $allSellPrice = 0;
        //总本金
        $allCostPrice = 0;
        //总邮费
        $allPostage = 0;
        //总优惠
        $allSale = 0;
        //总支付
        $allPayPrice = 0;

        //每个店铺的总价
        $shopPriceList = [];
        //每个商品的总价
        $goodsPriceList = [];

        $level_discount = $option['level_discount'] ?? 0; // [0, 1)
        // 当 levelDiscount>0 并且 couponDiscountBoth == 0 的时候，需要前端给用户选择使用优惠券还是折扣率
        $coupon_discount_both = $option['coupon_discount_both'] ?? 0;
        // 使用优惠类型：  coupon | discount | coupon_discount | '' 空字符串表示不需要优惠
        $useSale = $option['useSale'] ?? 0;
        if ($useSale == 'coupon' || $useSale == '') {
            $level_discount = 0;
        }
        // var_dump($level_discount);exit();
        foreach ($goodsInfo as $val) {
            $orderType    = $val['shopInfo']['orderType'];
            $shopPrice    = 0;
            $costPrice    = 0;
            $shopPostage  = 0;
            $subOrderSale = 0; // sub order sale
            $shopQuantity = 0;
            $shopPayPrice = 0;
            foreach ($val['goodsInfo'] as $goods) {
                $shopId = $goods['shopId'];

                $payPrice      = bcmul($goods['sellPrice'], $goods['quantity'], 2); //商品总支付金额 = 价格x数量
                $discount_sale = $level_discount > 0 ? bcmul($payPrice, (1 - $level_discount), 2) : 0; // 折扣金额

                $payPrice = bcadd($goods['postage'], $payPrice, 2); //商品总支付金额 = 价格x数量+ 邮费

                $subOrderSale  = bcadd($goods['sale'], $subOrderSale, 2); //商品总支付金额 = 价格x数量+ 邮费 - 优惠金额
                $subOrderSale  = bcadd($subOrderSale, $discount_sale, 2); // 子订单优惠金额 + 折扣
                $goods['sale'] = bcadd($goods['sale'], $discount_sale, 2); //商品总支付金额 = 价格x数量+ 邮费 - 优惠金额

                $shopPayPrice = bcadd($shopPayPrice, $payPrice, 2); //店铺总支付金额 = 原总金额+支付总金额
                $shopPayPrice = bcsub($shopPayPrice, $subOrderSale, 2); //店铺总支付金额 = 原总金额+支付总金额-优惠金额

                $shopPrice    = bcadd(bcmul($goods['sellPrice'], $goods['quantity'], 2), $shopPrice, 2); //店铺商品总价 = 商品价格x数量+其他商品总价
                $costPrice    = bcadd(bcmul($goods['costPrice'], $goods['quantity'], 2), $costPrice, 2); //店铺商品成本总价 = 商品成本价格x数量+其他商品成本总价
                $shopPostage  = bcadd($goods['postage'], $shopPostage, 2); //店铺总邮费 = 商品总邮费+其他商品总邮费
                $shopQuantity = bcadd($goods['quantity'], $shopQuantity); //店铺卖出数量 = 商品数量+其他数量

                // var_dump($discount_sale);exit;
                $goodsPriceList[] = [
                    'order_no'      => $orderNo,
                    'goods_id'      => $goods['id'],
                    'sku_id'        => $goods['skuId'],
                    'goods_img'     => $goods['goodsImg'],
                    'goods_title'   => $goods['goodsTitle'],
                    'sku_title'     => $goods['skuTitle'],
                    'shop_id'       => $goods['shopId'],
                    'user_id'       => $uId,
                    'sell_price'    => $goods['sellPrice'],
                    'cost_price'    => $goods['costPrice'],
                    'quantity'      => $goods['quantity'],
                    'postage'       => $goods['postage'],
                    'pay_price'     => bcsub($payPrice, $goods['sale'], 2),
                    'sale'          => $goods['sale'],
                    'remark'        => $goods['remark'],
                    'order_type'    => $goods['orderType'],
                    'gxz_rate'      => $goods['gxzRate'],
                    'platform_sale' => $goods['platform_sale'], // 平台优惠券优惠金额
                    'shop_sale'     => $goods['shop_sale'], // 店铺优惠券优惠金额
                    'discount_sale' => $discount_sale, // 平台会员等级折扣金额
                ];

                if (isset($shopPriceList[$shopId])) {
                    $shopPriceList[$shopId]['pay_price'] += $shopPayPrice;
                    $shopPriceList[$shopId]['sell_price'] += $shopPrice;
                    $shopPriceList[$shopId]['cost_price'] += $costPrice;
                    $shopPriceList[$shopId]['postage'] += $shopPostage;
                    $shopPriceList[$shopId]['quantity'] += $shopQuantity;
                    $shopPriceList[$shopId]['sale'] += $subOrderSale;
                    $shopPriceList[$shopId]['discount_sale'] += $discount_sale;
                } else {
                    $shopPriceList[$shopId] = [
                        'user_id'       => $uId,
                        'order_type'    => $orderType,
                        'order_no'      => $orderNo,
                        'shop_id'       => $val['shopInfo']['id'],
                        'shop_name'     => $val['shopInfo']['shopName'],
                        'pay_price'     => $shopPayPrice,
                        'sell_price'    => $shopPrice,
                        'cost_price'    => $costPrice,
                        'postage'       => $shopPostage,
                        'quantity'      => $shopQuantity,
                        'sale'          => $subOrderSale,
                        'discount_sale' => $discount_sale,
                    ];
                }
            }

            $allSellPrice = bcadd($allSellPrice, $shopPrice, 2);
            //总本金
            $allCostPrice = bcadd($costPrice, $allCostPrice, 2);
            //总邮费
            $allPostage = bcadd($shopPostage, $allPostage, 2);
            //总优惠
            $allSale = bcadd($subOrderSale, $allSale, 2);
            //总支付
            $allPayPrice = bcadd($shopPayPrice, $allPayPrice, 2);
        }
        // echo json_encode($goodsPriceList, 320);exit;
        // var_dump($allSale, $subOrderSale, $discount_sale, $level_discount);exit;
        $special_id = $option['special_id'] ?? 0;
        $allList    = [
            'user_id'    => $uId,
            'order_type' => $orderType,
            'order_no'   => $orderNo,
            'sell_price' => $allSellPrice,
            'cost_price' => $allCostPrice,
            'postage'    => $allPostage,
            'sale'       => $allSale,
            'pay_price'  => $allPayPrice,
            'special_id' => (int) $special_id,
            'expire_at'  => date('Y-m-d H:i:s', strtotime('+15 minutes')),
            'pay_amount' => 0,
        ];

        return ['shopPriceList' => array_values($shopPriceList), 'allList' => $allList, 'goodsPriceList' => $goodsPriceList];

    }

    public function getOrderInfo($orderNo, $uid): array
    {
        $where = [
            ['order_no', '=', $orderNo],
            ['user_id', '=', $uid],
        ];
        $order = Order::getInstance()
            ->where($where)
            ->find();
        return empty($order) ? [] : $order->toArray();
    }

    public function createOutlineOrder($shopInfo, $uid, $price, $skuId, $couponId, $option = [],$deduction)
    {
        // 1线下直付单 2线上单 3线下单 4供应链
        $orderType = 1;
        //总价
        $allSellPrice = $price;
        //总本金
        $allCostPrice = 0;
        //总邮费
        $allPostage = 0;
        //总优惠
        $allSale = 0;
        //总支付
        $allPayPrice = $price;

        [$level_discount, $coupon_discount_both] = \app\api\services\UserLevelService::getInstance()->levelDiscount(
            $uid
        ); // [0, 1)

        if($skuId && $shopInfo['shopType'] == 1){
            $orderType = 3;
        }

        // 使用优惠类型：  coupon | discount | coupon_discount
        $useSale       = $option['useSale'] ?? '';
        $discount_sale = 0;
        $postage       = 0;
        $orderNo       = getNo();
        $priceInfo     = [
            'allList'       => [
                'user_id'    => $uid,
                'order_type' => $orderType,
                'order_no'   => $orderNo,
                'sell_price' => $allSellPrice,
                'cost_price' => $allCostPrice,
                'postage'    => $postage,
                'sale'       => $discount_sale,
                'pay_price'  => $allPayPrice - $discount_sale - $deduction,
                // 'special_id' => 0,
                'expire_at'  => date('Y-m-d H:i:s', strtotime('+15 minutes')),
                'pay_amount' => 0,
                'deduction' => $deduction,
            ],
            'shopPriceList' => [
                [
                    'user_id'       => $uid,
                    'order_type'    => $orderType,
                    'order_no'      => $orderNo,
                    'pay_price'     => $allPayPrice - $discount_sale - $deduction,
                    'sell_price'    => $allSellPrice,
                    'cost_price'    => $allCostPrice,
                    'shop_id'       => $shopInfo['id'],
                    'shop_name'     => $shopInfo['shopName'],
                    'postage'       => $postage,
                    'quantity'      => 1,
                    'sale'          => 0 + $discount_sale,
                    'discount_sale' => $discount_sale,
                    'deduction' => $deduction,
                ],
            ],
        ];

        $goodsData = [];
        if ( ! empty($skuId)) {
            $sku         = GoodsSku::where('id', $skuId)->find();
            $goods       = GoodsService::getInstance()->goodsDetail($sku['goodsId']);
            $allPayPrice = $sku['sellPrice'];

            $discount_sale = $level_discount > 0 ? bcmul($allPayPrice, (1 - $level_discount), 2) : 0; // 折扣金额
            if ($useSale == 'coupon' || $useSale == '') {
                $discount_sale = 0;
            }

            // var_dump($shopInfo);exit;
            $priceInfo['goodsPriceList'] = [
                [
                    'order_no'      => $orderNo,
                    'goods_id'      => $goods['id'],
                    'sku_id'        => $skuId,
                    'goods_img'     => $goods['goodsImg'],
                    'goods_title'   => $goods['goodsTitle'],
                    'sku_title'     => $sku['skuTitle'],
                    'shop_id'       => $goods['shopId'],
                    'user_id'       => $uid,
                    'sell_price'    => $sku['sellPrice'],
                    'cost_price'    => $sku['costPrice'],
                    'quantity'      => 1,
                    'postage'       => 0,
                    'pay_price'     => $allPayPrice - $discount_sale,
                    'sale'          => $sku['sale'] + $discount_sale,
                    'discount_sale' => $discount_sale,
                    'remark'        => $sku['remark'],
                    'order_type'    => $orderType,
                    'gxz_rate'      => $goods['gxzRate'] > 0 ? $goods['gxzRate'] : $shopInfo['gxzRate'],
                    'platform_sale' => 0,
                    'shop_sale'     => 0,
                ],
            ];
            $priceInfo['allList']['sale']                   = $discount_sale;
            $priceInfo['allList']['pay_price']              = $allPayPrice - $discount_sale - $deduction;
            $priceInfo['allList']['sell_price']             = $allPayPrice;
            $priceInfo['allList']['cost_price']             = $sku['costPrice'];
            $priceInfo['allList']['deduction']              = $deduction;
            $priceInfo['shopPriceList'][0]['sell_price']    = $allPayPrice;
            $priceInfo['shopPriceList'][0]['cost_price']    = $sku['costPrice'];
            $priceInfo['shopPriceList'][0]['pay_price']     = $allPayPrice - $discount_sale - $deduction;
            $priceInfo['shopPriceList'][0]['sale']          = $discount_sale;
            $priceInfo['shopPriceList'][0]['discount_sale'] = $discount_sale;
            $priceInfo['shopPriceList'][0]['deduction']     = $deduction;

            if ($useSale != '' && ($useSale == 'coupon' || $useSale == 'coupon_discount')) {
                CouponService::getInstance()->getCouponPrice($priceInfo, $couponId, $uid);
            } else {
                $couponId = '';
            }
            // var_dump($couponId, $priceInfo);exit;
        }

        // var_dump($priceInfo['goodsPriceList']);exit;
        Order::getInstance()->startTrans();
        try {
            $order = Order::getInstance()->insert($priceInfo['allList']);
            if ( ! $order) {
                return false;
            }
            $order = OrderShop::getInstance()->insertAll($priceInfo['shopPriceList']);
            if ( ! $order) {
                Order::getInstance()->rollback();
                return false;
            }
            if ( ! empty($priceInfo['goodsPriceList'])) {
                OrderGoods::getInstance()->insertAll($priceInfo['goodsPriceList']);
            }
            CouponService::getInstance()->updateCouponInfo($couponId);
        } catch (\Exception $e) {
            Order::getInstance()->rollback();
            // var_dump($e->getMessage());exit;
            return false;
        }
        Order::getInstance()->commit();
        return $orderNo;
    }

    public function getOrderGoodsInfo($goodsInfos): array
    {
        $info = [];
        foreach ($goodsInfos as $v) {

            $goodsInfo = GoodsService::getInstance()->goodsDetail($v['goodsId']);
            if (empty($goodsInfo) || $goodsInfo['goodsType'] == 1 && $goodsInfo['goodsInventory'] < 1) {
                continue;
            }
            $shopInfo = ShopService::getInstance()->shopInfo($goodsInfo['shopId']);
            if (empty($shopInfo)) {
                continue;
            }
            // shopType 1线下 2线上
            // orderType 1线下直付单 2线上单 3线下单 4供应链
            if ($shopInfo) {
                $shopInfo['orderType'] = ($shopInfo['shopType'] == 1) ? 3 : 2;
            }

            if ($goodsInfo['isSku']) {
                $sku = GoodsService::getInstance()->skuInfo($v['goodsId'], $v['skuId'], 'id,sell_price,goods_inventory,cost_price,sku_img,sku_title');
                if (empty($sku)) {
                    continue;
                }
                $goodsInfo['sellPrice'] = $sku['sellPrice'];
                $goodsInfo['costPrice'] = $sku['costPrice'];
                $goodsInfo['goodsImg']  =  ! empty($sku['skuImg']) ? $sku['skuImg'] : $goodsInfo['goodsImg'];
            }
            $goodsInfo['orderType']     = $shopInfo['orderType'];
            $goodsInfo['skuTitle']      = $sku['skuTitle'] ?? '';
            $goodsInfo['skuId']         = $sku['id'] ?? 0;
            $goodsInfo['quantity']      = $v['quantity'];
            $goodsInfo['sale']          = 0; // 优惠金额
            $goodsInfo['remark']        = $v['remark'] ?? '';
            $goodsInfo['platform_sale'] = 0;
            $goodsInfo['shop_sale']     = 0;

            // 不包邮、关联运费模版ID为空，应当报错
            if ($goodsInfo['isPostage'] == 0 && $goodsInfo['spId'] == 0) {
                continue;
            }
            // isPostage 是否包邮  0否，1是  默认：1
            if ($goodsInfo['isPostage'] == 0) {
                $goodsInfo['postage'] = $this->getPostAge($goodsInfo['spId'], $v['quantity'], $goodsInfo['sellPrice']);
            } else {
                $goodsInfo['postage'] = 0;
            }
            $info[$shopInfo['id']]['goodsInfo'][] = $goodsInfo;
            $info[$shopInfo['id']]['shopInfo']    = $shopInfo;
        }
        return $info;
    }

    public function getPostAge($spId, $quantity, $sellPrice)
    {
        $spInfo = $this->getPost($spId);
        switch ($spInfo['type']) {
            case 1:
                return 0;
            case 2:
                $allPrice = bcmul($quantity, $sellPrice, 2);
                if ($allPrice >= $spInfo['quota']) {
                    return 0;
                } else {
                    return $spInfo['price'];
                }
            case 3:
                return bcmul($quantity, $spInfo['price'], 2);
        }
        return 0;
    }

    public function getPost($spId): array
    {
        $where = [
            ['id', '=', $spId],
            ['deleted', '=', 0],
        ];
        $spInfo = Postage::getInstance()->where($where)->find();
        return empty($spInfo) ? [] : $spInfo->toArray();
    }

}
